package com.joolun.weixin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.joolun.common.constant.Constants;
import com.joolun.common.corp.TenantContext;
import com.joolun.common.exception.base.BaseException;
import com.joolun.system.domain.*;
import com.joolun.system.mapper.ScrmStaffMapper;
import com.joolun.system.service.impl.SysCorpConfigServiceImpl;
import com.joolun.weixin.config.WxCpConfiguration;
import com.joolun.weixin.entity.WxCustomerLossInfo;
import com.joolun.weixin.entity.dto.WxCpXmlOutMessageDTO;
import com.joolun.weixin.entity.dto.WxCustomerLossInfoSaveDTO;
import com.joolun.weixin.entity.dto.WxStaffDeleteCustomerDTO;
import com.joolun.weixin.mapper.ScrmCustomerInfoMapper;
import com.joolun.weixin.service.*;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.impl.WxCpExternalContactServiceImpl;
import me.chanjar.weixin.cp.bean.external.WxCpUpdateRemarkRequest;
import me.chanjar.weixin.cp.bean.external.contact.ExternalContact;
import me.chanjar.weixin.cp.bean.external.contact.FollowedUser;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactBatchInfo;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * 企业微信客户详情信息 服务实现类
 * @author xxh
 * @since 2021-12-22
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class ScrmCustomerInfoServiceImpl extends ServiceImpl<ScrmCustomerInfoMapper, ScrmCustomerInfo> implements IScrmCustomerInfoService {
    @Autowired
    private ScrmCustomerInfoMapper scrmCustomerInfoMapper;

    @Autowired
    private ScrmStaffMapper scrmStaffMapper;

    @Autowired
    private IScrmCustomerStaffService customerStaffService;
    @Autowired
    private IScrmCustomerInfoService customerInfoService;
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IEduSchedulingClassService eduSchedulingClassService;

    @Autowired
    private IWxCustomerLossInfoService customerLossInfoService;
    @Autowired
    private  IScrmChannelRecordLogService scrmChannelRecordLogService;
    @Autowired
    private  IScrmChannelStatisticsService scrmChannelStatisticsService;
    @Autowired
    private SysCorpConfigServiceImpl sysCorpConfigService;



    @Override
    public ScrmCustomerInfo find(String extCorpId, String customerExtId, String staffExtId) {
        return baseMapper.find(extCorpId,customerExtId,staffExtId);
    }

    /**
     * 查询企业微信客户详情信息
     *
     * @param id 企业微信客户详情信息主键
     * @return 企业微信客户详情信息
     */
    @Override
    public ScrmCustomerInfo selectScrmCustomerInfoById(Integer id)
    {
        return scrmCustomerInfoMapper.selectScrmCustomerInfoById(id);
    }

    /**
     * 查询企业微信客户详情信息列表
     *
     * @param scrmCustomerInfo 企业微信客户详情信息
     * @return 企业微信客户详情信息
     */
    @Override
    public List<ScrmCustomerInfo> selectScrmCustomerInfoList(ScrmCustomerInfo scrmCustomerInfo)
    {
        // 添加主体id
        scrmCustomerInfo.setCorpId(TenantContext.getTenantId());
        return scrmCustomerInfoMapper.selectScrmCustomerInfoList(scrmCustomerInfo);
    }

    /**
     * 新增企业微信客户详情信息
     *
     * @param scrmCustomerInfo 企业微信客户详情信息
     * @return 结果
     */
    @Override
    public int insertScrmCustomerInfo(ScrmCustomerInfo scrmCustomerInfo)
    {
        // 添加主体id
        scrmCustomerInfo.setCorpId(TenantContext.getTenantId());
        return scrmCustomerInfoMapper.insertScrmCustomerInfo(scrmCustomerInfo);
    }

    /**
     * 修改企业微信客户详情信息
     *
     * @param scrmCustomerInfo 企业微信客户详情信息
     * @return 结果
     */
    @Override
    public int updateScrmCustomerInfo(ScrmCustomerInfo scrmCustomerInfo)
    {
        return scrmCustomerInfoMapper.updateScrmCustomerInfo(scrmCustomerInfo);
    }

    /**
     * 批量删除企业微信客户详情信息
     *
     * @param ids 需要删除的企业微信客户详情信息主键
     * @return 结果
     */
    @Override
    public int deleteScrmCustomerInfoByIds(Integer[] ids)
    {
        return scrmCustomerInfoMapper.deleteScrmCustomerInfoByIds(ids);
    }

    /**
     * 删除企业微信客户详情信息信息
     *
     * @param id 企业微信客户详情信息主键
     * @return 结果
     */
    @Override
    public int deleteScrmCustomerInfoById(Integer id)
    {
        return scrmCustomerInfoMapper.deleteScrmCustomerInfoById(id);
    }

    @Override
    public void staffDeleteCustomer(WxStaffDeleteCustomerDTO customerDTO) {

        Date deleteAt = new Date();
        // 1、新增流水
        ScrmStaff staff = scrmStaffMapper.selectOne(Wrappers.lambdaQuery(ScrmStaff.class).eq(ScrmStaff::getExtCorpId,customerDTO.getExtCorpId())
                .eq(ScrmStaff::getExtId,customerDTO.getStaffExtId()));

        ScrmCustomerInfo scrmCustomerInfo = scrmCustomerInfoMapper.selectOne(Wrappers.lambdaQuery(ScrmCustomerInfo.class)
                .eq(ScrmCustomerInfo::getExtCorpId,customerDTO.getExtCorpId())
                .eq(ScrmCustomerInfo::getExtCustomerId,customerDTO.getCustomerExtId()).
                eq(ScrmCustomerInfo::getExtStaffId,customerDTO.getStaffExtId())
                .eq(ScrmCustomerInfo::getHasFriend,true));

        if(scrmCustomerInfo == null){
            log.info("-----删除的客户信息不存在：{}",customerDTO.getCustomerExtId());
            return;
        }

        ScrmCustomerStaff customerStaff = customerStaffService.checkExists(scrmCustomerInfo.getExtCorpId(), staff.getExtId(), scrmCustomerInfo.getExtCustomerId());
        // 已经删除了员工和客户的关联关系
        if(customerStaff == null){
            return;
        }

        WxCustomerLossInfoSaveDTO wxCustomerLossInfoSaveDTO = new WxCustomerLossInfoSaveDTO()
                .setDeleteByTransfer(customerDTO.getDeleteByTransfer())
                .setStaffId(staff.getId()+"")
                .setCustomerId(scrmCustomerInfo.getId()+"")
                .setCustomerStaffId(customerStaff.getId()+"")
                .setExtCorpId(customerDTO.getExtCorpId())
                .setCreateTime(new Date())
                .setType(customerDTO.getType())
                .setDeleteTime(customerDTO.getDeleteTime())
                .setAddTime(customerStaff.getCreateTime())
                .setExtCustomerId(scrmCustomerInfo.getExtCustomerId());

        // 客户删除员工
        if (Objects.equals(WxCustomerLossInfo.TYPE_CUSTOMER_DELETE_STAFF, customerDTO.getType())) {
            log.info("客户删除员工");
            customerStaff.setIsDeletedStaff(true).setUpdatedAt(new Date());
            customerStaffService.updateById(customerStaff);

            long staffCount = customerStaffService.count(new LambdaQueryWrapper<ScrmCustomerStaff>()
                    .eq(ScrmCustomerStaff::getExtCorpId, customerDTO.getExtCorpId())
                    .eq(ScrmCustomerStaff::getExtCustomerId, scrmCustomerInfo.getExtCustomerId())
                    .and(wrapper -> wrapper.eq(ScrmCustomerStaff::getIsDeletedStaff, false)
                            .or()
                            .isNull(ScrmCustomerStaff::getIsDeletedStaff)));
            if (staffCount < 1) {
                scrmCustomerInfo.setHasDelete(null);
                scrmCustomerInfo.setFollowStatus("4");
                scrmCustomerInfo.setDeletedAt(new Date());
                updateById(scrmCustomerInfo);
            }
        } else {
            log.info("员工:{}删除客户:{}",staff.getExtId(),scrmCustomerInfo.getExtCustomerId());
            // 2、判断是否还有别的跟进人员，如果有则删除跟进关系、从客户旅程中移除，如果没有删除跟进关系,客户信息,客户详情信息,客户-标签
            if (OptionalLong.of(customerStaffService.count(new LambdaQueryWrapper<ScrmCustomerStaff>()
                    .eq(ScrmCustomerStaff::getExtCorpId, customerDTO.getExtCorpId())
                    .eq(ScrmCustomerStaff::getExtCustomerId, customerDTO.getCustomerExtId()))).orElse(0) < 2) {

                // 删除客户
                update(new LambdaUpdateWrapper<ScrmCustomerInfo>()
                        .eq(ScrmCustomerInfo::getId, scrmCustomerInfo.getId())
                        .set(ScrmCustomerInfo::getDeletedAt, deleteAt));
                removeById(scrmCustomerInfo.getId());

                // 记录删除的时候的客户旅程信息
//                wxCustomerLossInfoSaveDTO.setJourneyStageIds(Optional.ofNullable(journeyStageCustomerService.list(
//                                new LambdaQueryWrapper<BrJourneyStageCustomer>()
//                                        .eq(BrJourneyStageCustomer::getExtCorpId, customerDTO.getExtCorpId())
//                                        .eq(BrJourneyStageCustomer::getCustomerExtId, wxCustomer.getExtId())))
//                        .orElse(new ArrayList<>()).stream().map(BrJourneyStageCustomer::getJourneyStageId)
//                        .collect(Collectors.toList()));
//                journeyStageCustomerService.remove(new LambdaQueryWrapper<BrJourneyStageCustomer>()
//                        .eq(BrJourneyStageCustomer::getExtCorpId, customerDTO.getExtCorpId())
//                        .eq(BrJourneyStageCustomer::getCustomerExtId, wxCustomer.getId()));
            }
            if (null != customerStaff.getId()) {
                // 删除客户-员工关联
                customerStaffService.update(new LambdaUpdateWrapper<ScrmCustomerStaff>()
                        .eq(ScrmCustomerStaff::getId, customerStaff.getId())
                        .set(ScrmCustomerStaff::getDeletedAt, deleteAt));
                customerStaffService.removeById(customerStaff.getId());

                // 删除客户数据
                customerInfoService.update(new LambdaUpdateWrapper<ScrmCustomerInfo>()
                        .eq(ScrmCustomerInfo::getExtCorpId, customerStaff.getExtCorpId())
                        .eq(ScrmCustomerInfo::getExtStaffId, customerStaff.getExtStaffId())
                        .eq(ScrmCustomerInfo::getExtCustomerId, customerStaff.getExtCustomerId())
                        .set(ScrmCustomerInfo::getDeletedAt, deleteAt));
                customerInfoService.remove(new LambdaQueryWrapper<ScrmCustomerInfo>()
                        .eq(ScrmCustomerInfo::getExtCorpId, customerStaff.getExtCorpId())
                        .eq(ScrmCustomerInfo::getExtStaffId, customerStaff.getExtStaffId())
                        .eq(ScrmCustomerInfo::getExtCustomerId, customerStaff.getExtCustomerId()));

            }

            // 3、更新员工的客户数
            staff.setCustomerCount(
                    Math.toIntExact(OptionalLong.of(customerStaffService.count(new LambdaQueryWrapper<ScrmCustomerStaff>()
                            .eq(ScrmCustomerStaff::getExtCorpId, scrmCustomerInfo.getExtCorpId())
                            .eq(ScrmCustomerStaff::getExtStaffId, staff.getExtId()))).orElse(0)));
            scrmStaffMapper.updateById(staff);
        }

        // 更新当前排期班级的删友数
        EduSchedulingClass eduSchedulingClass = eduSchedulingClassService.getOne(Wrappers.lambdaQuery(EduSchedulingClass.class)
                .eq(EduSchedulingClass::getSchedulingId,scrmCustomerInfo.getSchedulingId()).eq(EduSchedulingClass::getWecomId,customerDTO.getStaffExtId()));
        if(eduSchedulingClass != null){
            //eduSchedulingClass.setFriendNum(eduSchedulingClass.getFriendNum() -1);
            eduSchedulingClass.setDelFriendNum(eduSchedulingClass.getDelFriendNum() +1);
            eduSchedulingClassService.updateFriendNum(eduSchedulingClass);
        }

        Long planId = scrmCustomerInfo.getPlanId();
        if(planId != null){
            // 更新统计数据
            ScrmChannelStatistics scrmChannelStatistics = scrmChannelStatisticsService.getOne(Wrappers.lambdaQuery(ScrmChannelStatistics.class).eq(ScrmChannelStatistics::getPlanId,scrmCustomerInfo.getPlanId()));
            if(scrmChannelStatistics != null){
                scrmChannelStatistics.setSyNum(scrmChannelStatistics.getSyNum() +1);
                scrmChannelStatisticsService.saveOrUpdate(scrmChannelStatistics);
            }
            // 添加行为记录-删友
            scrmChannelRecordLogService.changeFriend(scrmCustomerInfo,"DelFriend");
        }
        WxCustomerLossInfo wxCustomerLossInfo = customerLossInfoService.save(wxCustomerLossInfoSaveDTO.setStaffExtId(staff.getExtId()));
        log.info("新增流失记录,入参：【{}】,出参【{}】", wxCustomerLossInfoSaveDTO, wxCustomerLossInfo);

    }

    @Override
    public void releaseSyncLock(RLock lock) {
        // 判断要解锁的key是否被当前线程持有。
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }

    @Override
    public RLock getCustomerSyncLock(String extCorpId, String extId) {
        return redissonClient.getLock(Constants.CUSTOMER_SYNC_LOCK_PRE + extCorpId + ":" + extId);
    }


    @Override
    public boolean trySyncLock(RLock lock) throws InterruptedException {
        boolean result = lock.tryLock(10, 30, TimeUnit.SECONDS);
        if (!result) {
            log.error("[{}]客户同步信息尝试获取锁失败", lock.getName());
        }
        return result;
    }

    @Validated
    public ScrmCustomerInfo refreshCustomer(WxCpExternalContactBatchInfo.ExternalContactInfo externalContactInfo,
                                            WxCpXmlOutMessageDTO dto) {

        ExternalContact externalContact = externalContactInfo.getExternalContact();
        FollowedUser followInfo = externalContactInfo.getFollowInfo();
        String operatorUserId = followInfo.getOperatorUserId();
        String staffExtId = followInfo.getUserId();
        String customerExtId = externalContact.getExternalUserId();

        String unionId = externalContact.getUnionId();
        // 查询是否已经添加过企微客户信息
        ScrmCustomerInfo oldCustomer = getOne(Wrappers.lambdaQuery(ScrmCustomerInfo.class).eq(ScrmCustomerInfo::getUnionId,unionId)
                .eq(ScrmCustomerInfo::getExtCorpId,dto.getExtCorpId())
                .eq(ScrmCustomerInfo::getExtCustomerId,customerExtId)
                .eq(ScrmCustomerInfo::getExtStaffId,staffExtId)
                //.eq(ScrmCustomerInfo::getFollowStatus,"1")
                .eq(ScrmCustomerInfo::getHasDelete,0)
        );
       // ScrmCustomerInfo oldCustomer = checkExists(extCorpId, customerExtId);

        ScrmCustomerInfo customer = new ScrmCustomerInfo();
        BeanUtils.copyProperties(externalContact, customer);
        customer.setUnionId(externalContact.getUnionId());
        customer.setExtCorpId(dto.getExtCorpId());
        // 主体id
        customer.setCorpId(dto.getExtCorpId());
        customer.setExtCustomerId(customerExtId);

        if (oldCustomer != null) {
            customer.setUpdatedAt(new Date());
            customer.setHasDelete(oldCustomer.getHasDelete());
            customer.setExtCreatorId(oldCustomer.getExtCreatorId());
            customer.setCreatedAt(oldCustomer.getCreatedAt());
            customer.setId(oldCustomer.getId());
            customer.setExtStaffId(staffExtId);
            // 头像和性别第三方拿不到，暂时从公众号授权拿
            customer.setGender(externalContact.getGender());
            customer.setNicPic(externalContact.getAvatar());
            customer.setUpdateTime(new Date());
            customer.setNickname(externalContact.getName());
            customer.setRemark(followInfo.getRemark());
            customer.setState(followInfo.getState());
            customer.setFollowStatus("3");
            updateById(customer);
        } else {

            // 企微未回调，查询是否有未绑定的客户信息
            ScrmCustomerInfo updateCustomer = getOne(Wrappers.lambdaQuery(ScrmCustomerInfo.class).eq(ScrmCustomerInfo::getUnionId,unionId)
                            .eq(ScrmCustomerInfo::getExtCorpId,dto.getExtCorpId())
                            .eq(ScrmCustomerInfo::getFollowStatus,"1")
                            .eq(ScrmCustomerInfo::getHasDelete,0));
            if(updateCustomer == null){
                customer.setExtCreatorId(staffExtId);
                customer.setCreatedAt(new Date(followInfo.getCreateTime() * 1000));
                customer.setNickname(externalContact.getName());
                customer.setNicPic(externalContact.getAvatar());
                customer.setExtStaffId(staffExtId);
                customer.setGender(externalContact.getGender());
                customer.setHasDelete(0);
                customer.setHasFriend(1);
                customer.setCreateTime(new Date());
                //customer.setAddWechatType(followInfo.getAddWay());
                customer.setDescription(followInfo.getDescription());
                customer.setAddWechatType(followInfo.getAddWay());
                String remarkMobiles [] =followInfo.getRemarkMobiles();
                customer.setPhoneNumber(remarkMobiles.length > 0 ? followInfo.getRemarkMobiles()[0]:"");
                customer.setRemark(followInfo.getRemark());
                customer.setState(followInfo.getState());
                // 已加v
                customer.setFollowStatus("3");
                save(customer);
                // 获客链接自定义参数信息
                String state = followInfo.getState();
                String state2 = dto.getState();
                // 投放计划
                Long plan_id = 0L;
                // 排期id
                String scheduling_id = "";
                // 新客户，state2 长度16表示为扫码添加
                if(state2 != null && state2.length() == 16 && !state2.contains("-")){
                    // 根据自定义参数找到排期班级
                    EduSchedulingClass eduSchedulingClass = eduSchedulingClassService.getOne(Wrappers.lambdaQuery(EduSchedulingClass.class).eq(EduSchedulingClass::getState,state2));
                    // 更新班级过程数据，如：friend_num好友数，scan_num扫描数
                    if(eduSchedulingClass != null){
                        customer.setSchedulingId(eduSchedulingClass.getSchedulingId());
                        eduSchedulingClass.setScanNum(eduSchedulingClass.getScanNum() +1);
                        eduSchedulingClass.setFriendNum(eduSchedulingClass.getFriendNum() +1);
                        eduSchedulingClassService.updateFriendNum(eduSchedulingClass);
                    }
                }else if(state2 != null && state != null){
                    // 当前获客链接标记和销售标记是同一个的新用户
                    if(state2.equals(state)){
                        // 判断是否为我们的获客链接进的量
                        String[] stateArr = state2.split("-");
                        if("XCHK".equals(stateArr[0].trim())){
                            // 设置客户投放计划、排期
                            plan_id = Long.parseLong(stateArr[1]);
                            customer.setPlanId(plan_id);
                            scheduling_id = stateArr[2];
                            log.info("----新增客户：{}，投放计划：{}，排期：{}",customer.getNickname(), plan_id, scheduling_id);
                            customer.setSchedulingId(Long.parseLong(scheduling_id));
                            // 更新班级过程数据，如：friend_num好友数
                            // 根据排期id和销售企微号查询到对应的排期班级
                            EduSchedulingClass eduSchedulingClass = eduSchedulingClassService.getOne(Wrappers.lambdaQuery(EduSchedulingClass.class)
                                    .eq(EduSchedulingClass::getSchedulingId,scheduling_id).eq(EduSchedulingClass::getWecomId,staffExtId));
                            if(eduSchedulingClass != null){
                                eduSchedulingClass.setScanNum(eduSchedulingClass.getScanNum() +1);
                                eduSchedulingClass.setFriendNum(eduSchedulingClass.getFriendNum() +1);
                                eduSchedulingClassService.updateFriendNum(eduSchedulingClass);
                            }
                        }else{
                            // 自然客户
                            customer.setHasFriend(0);
                        }
                    }else{
                        // 这里不做任何操作，这里是测试删除的客户信息入口
                    }
                }else{
                    // 自然客户
                    customer.setHasFriend(0);
                }
                // 更新统计数据
                ScrmChannelStatistics scrmChannelStatistics = scrmChannelStatisticsService.getOne(Wrappers.lambdaQuery(ScrmChannelStatistics.class).eq(ScrmChannelStatistics::getPlanId,plan_id));
                if(scrmChannelStatistics != null){
                    customer.setPlanId(plan_id);
                    // 添加行为记录 -UV -留资 -加V
                    scrmChannelRecordLogService.add(plan_id,customerExtId,dto.getExtCorpId(),"UV");
                    scrmChannelRecordLogService.add(plan_id,customerExtId,dto.getExtCorpId(),"LiuZi");
                    scrmChannelRecordLogService.changeFriend(customer,"JV");
                    scrmChannelStatistics.setJvNum(scrmChannelStatistics.getJvNum() + 1);
                    scrmChannelStatisticsService.saveOrUpdate(scrmChannelStatistics);
                }
            }else{
                BeanUtils.copyProperties(updateCustomer, customer);
                customer.setExtCreatorId(staffExtId);
                customer.setExtCustomerId(customerExtId);
                customer.setExtStaffId(staffExtId);
                customer.setPhoneNumber(updateCustomer.getPhoneNumber());
                customer.setCreatedAt(new Date(followInfo.getCreateTime() * 1000));
                customer.setNickname(externalContact.getName());
                customer.setNicPic(externalContact.getAvatar());
                customer.setGender(externalContact.getGender());
                customer.setHasDelete(0);
                customer.setHasFriend(1);
                //customer.setAddWechatType(followInfo.getAddWay());
                customer.setDescription(followInfo.getDescription());
                customer.setAddWechatType(followInfo.getAddWay());
                String remarkMobiles [] =followInfo.getRemarkMobiles();
                customer.setDescription(remarkMobiles.length > 0 ? followInfo.getRemarkMobiles()[0]:"");
                customer.setRemark(followInfo.getRemark());
                customer.setState(followInfo.getState());
                // 已加v
                customer.setFollowStatus("3");
                updateById(customer);
            }

        }

        // 更新客户员工更进情况数据
        ScrmCustomerStaff oldCustomerStaff = customerStaffService.checkExists(dto.getExtCorpId(), staffExtId, customerExtId);
        ScrmCustomerStaff customerStaff = new ScrmCustomerStaff();
        BeanUtils.copyProperties(followInfo, customerStaff);
        customerStaff.setOperUserId(operatorUserId)
                .setRemarkMobiles(followInfo.getRemarkMobiles() != null ? Arrays.toString(followInfo.getRemarkMobiles()) : "")
                .setExtCreatorId(customer.getExtCreatorId())
                .setRemarkCorpName(followInfo.getRemarkCompany())
                .setExtStaffId(staffExtId)
                .setExtCustomerId(customerExtId)
                .setCustomerId(customer.getId()+"")
                .setExtCorpId(dto.getExtCorpId())
                .setCreateTime(new Date(followInfo.getCreateTime() * 1000))
                .setCreatedAt(new Date(followInfo.getCreateTime() * 1000));
        if (oldCustomerStaff != null) {
            customerStaff.setCreatedAt(oldCustomerStaff.getCreatedAt())
                    .setIsDeletedStaff(oldCustomerStaff.getIsDeletedStaff())
                    .setUpdatedAt(new Date())
                    .setId(oldCustomerStaff.getId());
            customerStaffService.updateById(customerStaff);
        } else {
            customerStaffService.save(customerStaff);
            // 刷新员工客户数
            ScrmStaff staff = scrmStaffMapper.selectOne(new QueryWrapper<ScrmStaff>().lambda().eq(ScrmStaff::getExtId, staffExtId).eq(ScrmStaff::getExtCorpId, dto.getExtCorpId()));
            if (staff != null) {
                staff.setCustomerCount(Optional.ofNullable(staff.getCustomerCount()).orElse(0) + 1);
                scrmStaffMapper.updateById(staff);
            }
        }
        return customer;
    }

    @Override
    public boolean countByCustomerId(String extCorpId, String extCustomerId) {
        return count(new QueryWrapper<ScrmCustomerInfo>().lambda()
                .eq(ScrmCustomerInfo::getExtCorpId, extCorpId)
                .eq(ScrmCustomerInfo::getExtCustomerId, extCustomerId)) > 0;
    }

    @Override
    public List<String> getAllExtId() {
        return list(new QueryWrapper<ScrmCustomerInfo>().lambda().select(ScrmCustomerInfo::getExtCustomerId))
                .stream().map(ScrmCustomerInfo::getExtCustomerId).collect(Collectors.toList());
    }

    @Override
    public ScrmCustomerInfo checkExists(String extCorpId, String extId) {
        return getOne(new LambdaQueryWrapper<ScrmCustomerInfo>()
                .eq(ScrmCustomerInfo::getExtCorpId, extCorpId)
                .eq(ScrmCustomerInfo::getExtCustomerId, extId)
                .eq(ScrmCustomerInfo::getHasFriend, true));
    }

    @Override
    public List<RLock> getCustomerSyncLock(String extCorpId) {
        return getCustomerSyncLock(extCorpId, false);
    }

    @Override
    public List<RLock> getCustomerSyncLock(String extCorpId, boolean needCache) {

        // 查出全部员工id
        List<ScrmStaff> list = scrmStaffMapper.selectList(new QueryWrapper<ScrmStaff>().lambda()
                .eq(ScrmStaff::getExtCorpId, extCorpId)
                .select(ScrmStaff::getExtId));
        List<String> staffExtIds = list.stream().map(ScrmStaff::getExtId).collect(Collectors.toList());
        // 获取主体配置
        SysCorpConfig sysCorpConfig = sysCorpConfigService.getConfig(TenantContext.getTenantId());
        // 批量遍历同步数据（每次同步100个员工的客户数据）
        WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(
                WxCpConfiguration.getCustomerSecretWxCpService(sysCorpConfig));

        Set<String> customerExtIds = new HashSet<>();
        Lists.partition(staffExtIds, 100).forEach(staffIds -> {

            // 调用批量获取客户信息接口（每次最多只能获取100条数据，因此得递归分页获取所有的）
            WxCpExternalContactBatchInfo contactDetailBatch = null;
            try {
                contactDetailBatch = externalContactService.getContactDetailBatch(staffIds.toArray(new String[0]), null,
                        100);
                List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalContactList = contactDetailBatch
                        .getExternalContactList();
                getContactDetailBatch(externalContactService, externalContactList, staffIds,
                        contactDetailBatch.getNextCursor());
                externalContactList.forEach(e -> customerExtIds.add(e.getExternalContact().getExternalUserId()));
                // 把信息放入缓存
//                if (needCache) {
//                    // 获取名称为 "objectList" 的RList实例
//                    RList<WxCpExternalContactBatchInfo.ExternalContactInfo> rList = redissonClient
//                            .getList(Constants.WX_CUSTOMER_SYNC_INFOS + extCorpId);
//                    // 清空已存在的列表数据
//                    rList.delete();
//                    if (CollectionUtil.isNotEmpty(externalContactList)) {
//                        // 将对象列表添加到RList中
//                        rList.addAll(externalContactList);
//                    }
//                }
            } catch (WxErrorException e) {
                log.error("获取客户信息失败！", e);
                throw BaseException.buildBaseException(e.getError(), "获取客户信息失败");
            }

        });
        // 每个员工都上锁
        return customerExtIds.stream().map(e -> getCustomerSyncLock(extCorpId, e)).collect(Collectors.toList());
    }

    /**
     *
     * @param externalContactService 调用企业微信接口服务
     * @param list 客户基本信息
     * @param staffIds 员工id
     * @param nextCursor 分页游标，再下次请求时填写以获取之后分页的记录，如果已经没有更多的数据则返回空
     * @throws WxErrorException
     */
    private void getContactDetailBatch(WxCpExternalContactService externalContactService,
                                       List<WxCpExternalContactBatchInfo.ExternalContactInfo> list,
                                       List<String> staffIds, String nextCursor) throws WxErrorException {
        if (StringUtils.isBlank(nextCursor)) {
            return;
        }
        WxCpExternalContactBatchInfo contactDetailBatch = externalContactService.getContactDetailBatch(staffIds.toArray(new String[0]), nextCursor, 100);
        List<WxCpExternalContactBatchInfo.ExternalContactInfo> externalContactList = contactDetailBatch.getExternalContactList();
        if (CollectionUtil.isNotEmpty(externalContactList)) {
            list.addAll(contactDetailBatch.getExternalContactList());
        }
        String next = contactDetailBatch.getNextCursor();
        if (StringUtils.isNotBlank(next)) {
            getContactDetailBatch(externalContactService, list, staffIds, next);
        }
    }

    @Override
    public void updateRemark(WxCpUpdateRemarkRequest wxCpUpdateRemarkRequest, String extCorpId)
            throws WxErrorException {
        // 获取主体配置
        SysCorpConfig sysCorpConfig = sysCorpConfigService.getConfig(TenantContext.getTenantId());
        WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(
                WxCpConfiguration.getCustomerSecretWxCpService(sysCorpConfig));
        externalContactService.updateRemark(wxCpUpdateRemarkRequest);

        ScrmCustomerStaff customerStaff = customerStaffService.checkExists(extCorpId, wxCpUpdateRemarkRequest.getUserId(),
                wxCpUpdateRemarkRequest.getExternalUserId());
        if (customerStaff != null) {
            customerStaff.setRemark(wxCpUpdateRemarkRequest.getRemark()).setUpdatedAt(new Date());
            customerStaffService.updateById(customerStaff);
        }

    }

    @Override
    public int updateJoinGrop(List<String> userIds,String owner){
        return baseMapper.updateJoinGrop(userIds,owner);
    }


}
